package jhavelogger.parser;

import static org.junit.Assert.*;

import java.util.HashSet;
import java.util.Hashtable;

import jhavelogger.models.UnparsedLog;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public abstract class LogFactoryTestingBase {
    protected enum LogMessageType {
	KILLCONNECTION, KILLCLIENT, ACCEPTEDCONNECTION, PARTIALEXCEPTION, UIDOPERATION, USERNAMELOOKUPNOUSERNAME, USERNAMELOOKUPWITHUSERNAME, SENDALGORITHM, SENDALGORITHMWITHSUBALGORITHM
    };

    protected LogFactory factory;

    private Hashtable<LogMessageType, String> logMessages;

    @Before
    public void setUp() throws Exception {
	this.logMessages = new Hashtable<LogMessageType, String>();

	String killLog = "1/31/08 4:38 PM - FINE: killConnection: Communication Error.";
	this.logMessages.put(LogMessageType.KILLCONNECTION, killLog);

	String killClient = "1/31/08 4:38 PM - FINE: Killing client 424";
	this.logMessages.put(LogMessageType.KILLCLIENT, killClient);
	
	String acceptedCon = "1/31/08 5:35 PM - INFO: Accepted connection 425 from 128.44.42.39";
	this.logMessages.put(LogMessageType.ACCEPTEDCONNECTION, acceptedCon);
	
	String partialExcept = "        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1267)"; 
	this.logMessages.put(LogMessageType.PARTIALEXCEPTION, partialExcept);
	
	String uidOp = "2/1/08 1:12 AM - INFO: /srv/www/htdocs/jhave/html_root/uid/426 *";
	this.logMessages.put(LogMessageType.UIDOPERATION, uidOp);
	
	String algLookup = "2/1/08 1:12 AM - FINE: up front looking for -- exe/mergemyles/mergemyles"; 
	this.logMessages.put(LogMessageType.USERNAMELOOKUPNOUSERNAME, algLookup);
	
	String algUser = "3/29/11 5:33 PM - FINE: Up front with user  no_username looking for -- exe/insertionmyles/insertionmyles"; 
	this.logMessages.put(LogMessageType.USERNAMELOOKUPWITHUSERNAME, algUser);
	
	String sendAlgorithmWithSubAlgorithm = "3/21/11 10:15 AM - FINE: sendtoClient - 400 memorymanager/exercise1.jp gaigs";
	this.logMessages.put(LogMessageType.SENDALGORITHMWITHSUBALGORITHM, sendAlgorithmWithSubAlgorithm);
	
	String sendAlgorithm = "3/20/11 9:01 PM - FINE: sendtoClient - 400 rbtreemyles gaigs";
	this.logMessages.put(LogMessageType.SENDALGORITHM, sendAlgorithm);
    }

    protected boolean factoryCreatesObject(LogMessageType logMessageType) {
	String logMessage = this.logMessages.get(logMessageType);
	if (logMessage == null) {
	    throw new IllegalAccessError(
		    "There is not an entry in the logMessages hashtable for the provided log message type: "
			    + logMessageType.name());
	}

	return this.factory.create(new UnparsedLog("127.0.0.1", logMessage)) != null;
    }

    /**
     * Ensures that this factory will not create any LogMessages of any type
     * other than the types that it is supposed to.
     * 
     * @param logMessageTypes
     *            the types of log messages that this factory is allowed to
     *            create
     * @return the name of the log message type that the factory tried to create
     *         (but was not allowed to create). Returns null if the factory did
     *         not return an object it was not supposed to.
     */
    protected String factoryDoesNotCreateObjectsOfTypesOtherThan(
	    HashSet<LogMessageType> logMessageTypes) {
	for (LogMessageType t : this.logMessages.keySet()) {
	    if (!logMessageTypes.contains(t)) {
		String logMessage = this.logMessages.get(t);
		if (logMessage == null) {
		    throw new IllegalAccessError(
			    "There is not an entry in the logMessages hashtable for the provided log message type: "
				    + t.name());
		}

		if (this.factory.create(new UnparsedLog("127.0.0.1", logMessage)) != null) {
		    return t.name();
		}
	    }
	}

	return null;
    }
}
